#include "stdafx.h"
#include "ASN1Integer.h"

typedef std::pair<int, std::vector<byte>> integerEncodingParam;

class ASN1IntegerEncodingTestCase : public ::testing::TestWithParam<integerEncodingParam>
{
};

TEST_P(ASN1IntegerEncodingTestCase, Encode)
{
	AppliedCryptography::ASN1Integer val(GetParam().first);
	std::vector<byte> ret;

	ret = val.encode();

	// Output size should be as expected
	ASSERT_EQ(GetParam().second.size(), ret.size()) << "Value: " << val.get();

	for(unsigned int i = 0; i < GetParam().second.size(); ++i)
	{
		EXPECT_NO_THROW(EXPECT_EQ((int)GetParam().second.at(i), (int)ret.at(i)) 
			<< "Index i: " << i << "\n"
			<< "Value: " << val.get());
	};
};

byte bytes0[] = {0x02, 0x01, 0x00};
std::vector<byte> vect0(bytes0, bytes0 + sizeof(bytes0) / sizeof(byte));

byte bytes127[] = {0x02, 0x01, 0x7F};
std::vector<byte> vect127(bytes127, bytes127 + sizeof(bytes127) / sizeof(byte));

byte bytesNegative129[] = {0x02, 0x02, 0xFF, 0x7F};
std::vector<byte> vectNegative129(bytesNegative129, bytesNegative129 + sizeof(bytesNegative129) / sizeof(byte));

byte bytesNegative128[] = {0x02, 0x01, 0x80};
std::vector<byte> vectNegative128(bytesNegative128, bytesNegative128 + sizeof(bytesNegative128) / sizeof(byte));

byte bytes256[] = {0x02, 0x02, 0x01, 0x00};
std::vector<byte> vect256(bytes256, bytes256 + sizeof(bytes256) / sizeof(byte));

byte bytes128[] = {0x02, 0x02, 0x00, 0x80};
std::vector<byte> vect128(bytes128, bytes128 + sizeof(bytes128) / sizeof(byte));

byte bytesMany[] = {0x02, 0x04, 0x01, 0x00, 0x00, 0x06};
std::vector<byte> vectMany(bytesMany, bytesMany + sizeof(bytesMany) / sizeof(byte));

INSTANTIATE_TEST_CASE_P(ASN1IntegerEncodingTest,
                        ASN1IntegerEncodingTestCase,
						::testing::Values( 
							integerEncodingParam(0,	vect0), 
							integerEncodingParam(127,	vect127), 
							integerEncodingParam(-129,	vectNegative129), 
							integerEncodingParam(-128,	vectNegative128), 
							integerEncodingParam(256,	vect256), 
							integerEncodingParam(128,	vect128),
							integerEncodingParam(16777222,	vectMany) )
						);
